package com.sgai.zero_robot.base;

import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.ColorRes;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.viewbinding.ViewBinding;
import com.gyf.immersionbar.BarHide;
import com.gyf.immersionbar.ImmersionBar;
import com.sgai.zero_robot.R;
import com.sgai.zero_robot.pop.AlarmDialog;
import com.sgai.zero_robot.pop.LoadingDialog;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;


/**
 * activity 封装
 * Created by Administrator on 2021/10/27 0027.
 */
public abstract class BaseActivity<VB extends ViewBinding, VM extends BaseViewModel> extends AppCompatActivity {

    //viewbind
    protected VB mBinding;
    //viewmodel
    protected VM mViewModel;
    protected String TAG;
    protected Context mContext;
    private AlarmDialog alarmDialog;
    protected boolean isWindowChange(){
        return true;
    }
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        if (isWindowChange()){
            if (hasFocus) {
                try{
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                        Window window = getWindow();
                        WindowInsetsController controller = window.getInsetsController();
                        if (controller != null) {
                            controller.hide(WindowInsets.Type.navigationBars() | WindowInsets.Type.statusBars());
                            controller.setSystemBarsBehavior(
                                    WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
                            );
                        }
                    } else {
                        getWindow().getDecorView().setSystemUiVisibility(
                                View.SYSTEM_UI_FLAG_FULLSCREEN
                                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                        );
                    }
                    final View decorView = getWindow().getDecorView();
                    decorView.setOnSystemUiVisibilityChangeListener(visibility -> {
                        if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                            decorView.setSystemUiVisibility(
                                    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            );
                        }
                    });
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        super.onWindowFocusChanged(hasFocus);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ImmersionBar.with(this)
                .fullScreen(true)      //有导航栏的情况下，activity全屏显示，也就是activity最下面被导航栏覆盖，不写默认非全屏
                .hideBar(BarHide.FLAG_HIDE_BAR)  //隐藏状态栏或导航栏或两者，不写默认不隐藏
                .keyboardEnable(true)  //解决软键盘与底部输入框冲突问题，默认为false，还有一个重载方法，可以指定软键盘mode
                .keyboardMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)  //单独指定软键盘模式
                .init();  //必须调用方可应用以上所配置的参数
        final ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        try {
            //实例化泛型类
            Class<VB> entityClass = (Class<VB>) type.getActualTypeArguments()[0];
            Method method = entityClass.getMethod("inflate", LayoutInflater.class);//get method from name "inflate";
            mBinding = (VB) method.invoke(entityClass, getLayoutInflater());//execute method to create a objct of viewbind;
        } catch (Exception e) {
            e.printStackTrace();
        }
        Class<VM> vmClass = (Class<VM>) type.getActualTypeArguments()[1];
        mViewModel = new ViewModelProvider(this, getViewModelFactory()).get(vmClass);
        setContentView(mBinding.getRoot());
        mContext = this;
     /*   try {
            //设置坚屏 一定要放到try catch里面，否则会崩溃
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        } catch (Exception e) {
        }*/
        TAG = this.getClass().getSimpleName();
        initViews(savedInstanceState);//初始化UI
        mViewModel.onCreate(this);
        loadData();//加载数据
    }

    public abstract void initViews(Bundle savedInstanceState);

    public abstract void loadData();

    /**
     * 是否为空
     *
     * @param object
     * @return
     */
    public boolean isNull(Object object) {
        return object == null || object.toString().trim().equals("") || object.equals("null");
    }

    /**
     * viewmodel 工厂创建实例
     *
     * @return
     */
    public ViewModelProvider.Factory getViewModelFactory() {
        return ViewModelFactory.getInstance();
    }


    /**
     * 修改状态栏颜色，支持4.4以上版本
     *
     * @param colorId
     */
    public void setStatusBarBgColor(@ColorRes int colorId) {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        getWindow().setStatusBarColor(getResources().getColor(colorId));
    }

    /**
     * 修改状态栏文本颜色
     *
     * @param isBlack
     */
    public void setStatusBarTextColor(boolean isBlack) {
        View decor = getWindow().getDecorView();
        if (isBlack) {
            decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        } else {
            decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        }
    }

    /**
     * 隐藏虚拟按键
     */
    public void hideBottomUIMenu() {
        //隐藏虚拟按键
        if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
            View v = getWindow().getDecorView();
            v.setSystemUiVisibility(View.GONE);
        } else if (Build.VERSION.SDK_INT >= 19) {
            //for new api versions.
            View decorView = getWindow().getDecorView();
            int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
            decorView.setSystemUiVisibility(uiOptions);
        }

    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {  //把操作放在用户点击的时候
            View v = getCurrentFocus();      //得到当前页面的焦点,ps:有输入框的页面焦点一般会被输入框占据
            if (isShouldHideKeyboard(v, ev)) { //判断用户点击的是否是输入框以外的区域
                hideSoftKeyboard();   //收起键盘
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时则不能隐藏
     *
     * @param v
     * @param event
     * @return
     */
    private boolean isShouldHideKeyboard(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {  //判断得到的焦点控件是否包含EditText
            int[] l = {0, 0};
            v.getLocationInWindow(l);
            int left = l[0],    //得到输入框在屏幕中上下左右的位置
                    top = l[1],
                    bottom = top + v.getHeight(),
                    right = left + v.getWidth();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 点击位置如果是EditText的区域，忽略它，不收起键盘。
                return false;
            } else {
                return true;
            }
        }
        // 如果焦点不是EditText则忽略
        return false;
    }

    /**
     * 判断软键盘输入法是否弹出
     */
    public boolean isKeyboardVisbility(Context context, View v) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(context.INPUT_METHOD_SERVICE);
        if (imm.hideSoftInputFromWindow(v.getWindowToken(), 0)) {
            imm.showSoftInput(v, 0);
            return true;//键盘显示中
        } else {
            return false;//键盘未显示
        }
    }

    protected void hideSoftKeyboard() {
        if (getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) {
            if (getCurrentFocus() != null)
                ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    /**
     * 状态栏高度
     *
     * @return
     */
    public int getStatusBarHeight() {
        int result = 0;
        int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resId > 0) {
            result = getResources().getDimensionPixelOffset(resId);
        }
        return result;
    }


    long mExitTime = 0;

    /**
     * 返回键退出程序
     */
    public void backExit() {
        if ((System.currentTimeMillis() - mExitTime) > 2000) {
            Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show();
            mExitTime = System.currentTimeMillis();
        } else {
            BaseApplication.getInstance().quitApp();
        }
    }

    public void showToast(String message) {
        Log.i(TAG, "showToast " + message);
        runOnUiThread(() -> Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show());
    }

    public void showToast(@StringRes int msg) {
        showToast(getString(msg));
    }

    private LoadingDialog loadingDialog;

    public void showLoading(String message) {
        if (loadingDialog != null) {
            loadingDialog.setContent(message);
            return;
        }
        loadingDialog = new LoadingDialog(this);
        loadingDialog.setContent(message);
        loadingDialog.show();
    }

    public void dismissLoading() {
        if (loadingDialog != null) {
            loadingDialog.dismiss();
        }
        loadingDialog = null;
    }

    /**
     *
     * @param type  1是红色告警  2是黄色告警
     * @param title
     * @param msg
     * @param alarmCallback
     */
    protected void showAlarm(int type, String title, String msg, AlarmDialog.AlarmCallback alarmCallback) {
        if (alarmDialog != null) {
            alarmDialog.dismiss();
        }
        alarmDialog = new AlarmDialog(this);
        alarmDialog.setContent(type, title, msg);
        alarmDialog.setAlarmCallback(alarmCallback);
        alarmDialog.show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (alarmDialog != null) {
            alarmDialog.dismiss();
        }
    }

    protected int getMBattery(int battery) {
        if (battery > 75) {
            return R.mipmap.mobile4;
        } else if (battery > 50) {
            return R.mipmap.mobile3;
        } else if (battery > 25) {
            return R.mipmap.mobile2;
        } else if (battery > 0) {
            return R.mipmap.mobile1;
        } else {
            return R.mipmap.mobile0;
        }

    }

    protected void setBatteryTextColor(TextView textView, int percent) {
        String message = percent + "%";
        if (percent > 75) {
            textView.setTextColor(Color.parseColor("#1CEC41"));
        } else if (percent > 50) {
            textView.setTextColor(Color.parseColor("#1CEC41"));
        } else if (percent > 25) {
            textView.setTextColor(Color.parseColor("#FBC877"));
        } else if (percent > 0) {
            textView.setTextColor(Color.parseColor("#ff0000"));
        } else {
            textView.setTextColor(Color.parseColor("#ff0000"));
        }
        textView.setText(message);
    }

    protected int getRBattery(int battery) {
        if (battery > 75) {
            return R.mipmap.robot4;
        } else if (battery > 50) {
            return R.mipmap.robot3;
        } else if (battery > 25) {
            return R.mipmap.robot2;
        } else if (battery > 0) {
            return R.mipmap.robot1;
        } else {
            return R.mipmap.robot0;
        }
    }
}
